<?php
// +-------------------------------------------------------------------
// |
// +-------------------------------------------------------------------
// | Copyright (c) 2009-2016 All rights reserved.
// +-------------------------------------------------------------------
namespace Service\User;

class MoneyLog extends \Service\Common\BaseModel
{
    protected $name = 'money_log';

    const MONEY_LOG_TYPE_ORDER = 0;//订单
    const MONEY_LOG_TYPE_RECHARGE = 1;//后台充值
    const MONEY_LOG_TYPE_REMIT = 2;//后台汇款审核通过
    const MONEY_LOG_TYPE_COMMISSION_SALE = 3;//销售佣金
    const MONEY_LOG_TYPE_COMMISSION_MANAGE = 4;//管理层佣金
    const MONEY_LOG_TYPE_DRAW = 5;//提现冻结
    const MONEY_LOG_TYPE_DRAW_UNFREEZE = 6;//提现驳回
    const MONEY_LOG_TYPE_DRAW_SUCCESS = 7;//提现成功
    const MONEY_LOG_TYPE_TRANSFER_OUT = 8;//余额转出
    const MONEY_LOG_TYPE_TRANSFER_IN = 9;//余额转入
    const MONEY_LOG_TYPE_COMMISSION_PARENT = 10;//一代销售佣金
    const MONEY_LOG_TYPE_RED_PACKETS = 11;//红包转余额
    const MONEY_LOG_TYPE_MALL_MONTH_BONUS = 12;//商城月分红
    const MONEY_LOG_TYPE_MALL_YEAR_BONUS = 13;//商城年分红
    const MONEY_LOG_TYPE_AGENT = 14;//推荐代理分成
    const MONEY_LOG_TYPE_REBUY = 15;//重复消费奖励
    const MONEY_LOG_TYPE_AGENT2 = 16;//代理奖励
    const MONEY_LOG_TYPE_YEJI = 17;//业绩奖励
    const MONEY_LOG_TYPE_DOCK = 18;//扣钱
    const MONEY_LOG_TYPE_TEAM = 19;//扣钱

    const TYPE_LABEL = [
        self::MONEY_LOG_TYPE_ORDER => '订单',
        self::MONEY_LOG_TYPE_RECHARGE => '充值',
        self::MONEY_LOG_TYPE_REMIT => '汇款',
        self::MONEY_LOG_TYPE_COMMISSION_SALE => '佣金',
        self::MONEY_LOG_TYPE_COMMISSION_MANAGE => '分红',
        self::MONEY_LOG_TYPE_DRAW => '提现冻结',
        self::MONEY_LOG_TYPE_DRAW_UNFREEZE => '提现驳回',
        self::MONEY_LOG_TYPE_DRAW_SUCCESS => '提现成功',
        self::MONEY_LOG_TYPE_TRANSFER_OUT => '余额转出',
        self::MONEY_LOG_TYPE_TRANSFER_IN => '余额转入',
        self::MONEY_LOG_TYPE_COMMISSION_PARENT => '代付佣金',
        self::MONEY_LOG_TYPE_RED_PACKETS => '红包转余额',
        self::MONEY_LOG_TYPE_MALL_MONTH_BONUS => '商城月分红',
        self::MONEY_LOG_TYPE_MALL_YEAR_BONUS => '商城年分红',
        self::MONEY_LOG_TYPE_AGENT => '推荐代理分成',
        self::MONEY_LOG_TYPE_REBUY => '重复消费奖励',
        self::MONEY_LOG_TYPE_AGENT2 => '代理奖励',
        self::MONEY_LOG_TYPE_YEJI => '业绩奖励（月结）',
        self::MONEY_LOG_TYPE_DOCK => '扣钱',
        self::MONEY_LOG_TYPE_TEAM => '团队奖励'
    ];

    //余额转账
    public function transfer($uid, $to_uid, $money, $transfer_id)
    {
        //转出
        $this->changeBalance($uid, -$money, self::MONEY_LOG_TYPE_TRANSFER_OUT, $transfer_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'total_transfer_out' => ['exp', "total_transfer_out+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计转出金额失败");
        }
        //转入
        $this->changeBalance($to_uid, $money, self::MONEY_LOG_TYPE_TRANSFER_IN, $transfer_id);
        $update = M('user')->where(['uid' => $to_uid])->save([
            'total_transfer_in' => ['exp', "total_transfer_in+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计转入金额失败");
        }

        //转账收款通知
        OE('user')->addReceiveTransfer([
            'uid' => $to_uid,
            'transfer_name' => M('user')->where(['uid' => $uid])->getField('real_name'),
            'transfer_money' => $money,
            'transfer_id' => $transfer_id,
        ]);

        return true;
    }

    //资金明细
    public function moneyList($uid, $page_num = 1, $page_size = 5)
    {
        $where = [
            'uid' => $uid,
        ];
        $list = (array)$this->where($where)->order('id desc')->page($page_num, $page_size)->select();
        foreach ($list as &$row) {
            $row['type_label'] = self::TYPE_LABEL[$row['type']];
        }
        $count = $this->where($where)->count();
        return [
            $list,
            $page_count = $count,
            $page_total = ceil($count / $page_size),
        ];
    }

    //提现冻结
    public function drawMoney($uid, $money, $draw_cash_id)
    {
        $this->changeBalance($uid, -$money, self::MONEY_LOG_TYPE_DRAW, $draw_cash_id);
        //冻结资金
        $money = abs($money);
        $update = M('user')->where(['uid' => $uid])->save([
            'frozen_money' => ['exp', "frozen_money+$money"],
            'update_time' => date('Y-m-d H:i:s')
        ]);
        if ($update === false) {
            throw new \Exception("冻结资金失败");
        }
        return true;
    }

    //解冻提现
    public function unfreezeDrawMoney($uid, $money, $draw_cash_id)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_DRAW_UNFREEZE, $draw_cash_id);
        //解冻资金
        $update = M('user')->where(['uid' => $uid])->save([
            'frozen_money' => ['exp', "frozen_money-$money"],
            'update_time' => date('Y-m-d H:i:s')
        ]);
        if ($update === false) {
            throw new \Exception("冻结资金失败");
        }
        return true;
    }

    //提现成功
    public function drawMoneySuccess($uid, $money, $draw_cash_id)
    {
        $this->changeBalance($uid, 0, self::MONEY_LOG_TYPE_DRAW_SUCCESS, $draw_cash_id);
        //解冻资金
        $update = M('user')->where(['uid' => $uid])->save([
            'frozen_money' => ['exp', "frozen_money-$money"],
            'update_time' => date('Y-m-d H:i:s'),
            'total_draw_cash' => ['exp', "total_draw_cash+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("解冻资金失败");
        }

        //提现成功通知
        OE('user')->addDrawMoney([
            'uid' => $uid,
            'draw_money' => $money,
            'draw_id' => $draw_cash_id,
        ]);

        return true;
    }

    //汇款
    public function remit($uid, $money, $remit)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_REMIT, $remit['id']);
        $update = M('user')->where(['uid' => $remit['uid']])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_remit' => ['exp', "total_remit+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计汇款失败");
        }
        OE('user')->upgradeLeaderLevel($remit['uid']);

        //汇款成功通知
        OE('user')->addRemit($remit);
    }

    //充值
    public function recharge($uid, $money)
    {
        return $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_RECHARGE);
    }

    //充值
    public function dock($uid, $money)
    {
        return $this->changeBalance($uid, -$money, self::MONEY_LOG_TYPE_DOCK);
    }

    //商城月分红
    public function mallMonthBonus($uid, $money)
    {
        return $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_MALL_MONTH_BONUS);
    }

    //商城年分红
    public function mallYearBonus($uid, $money)
    {
        return $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_MALL_YEAR_BONUS);
    }

    //订单支付
    public function pay($uid, $money, $order)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_ORDER, $order['id']);
        $money = abs($money);
        $update = M('user')->where(['uid' => $order['uid']])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_buy' => ['exp', "total_buy+$money"],//累计购买消费
            'total_contribution' => ['exp', "total_contribution+{$order['order_contribution']}"]//累计贡献
        ]);
        if ($update === false) {
            throw new \Exception("累计消费购物失败");
        }
        //升级管理级别
        OE('user')->upgradeManageLevel($order['uid']);
        //累计订单代付
        if ($uid != $order['uid']) {
            $update = M('user')->where(['uid' => $uid])->save([
                'update_time' => date('Y-m-d H:i:s'),
                'total_invite_pay' => ['exp', "total_invite_pay+$money"],
                'total_invite_fee' => ['exp', "total_invite_fee+{$order['friend_fee_money']}"],
            ]);
            if ($update === false) {
                throw new \Exception("累计消费购物失败");
            }

            //代付通知
            OE('user')->invitePay($order);
        }
    }

    //销售佣金
    public function commissionSale($uid, $money, $order_id, $level)
    {
        if($money<=0) return false;
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_COMMISSION_SALE, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_sale{$level}_commission" => ['exp', "total_sale{$level}_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计销售佣金失败");
        }
    }

    //管理佣金
    public function commissionManage($uid, $money, $order_id)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_COMMISSION_MANAGE, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_manage_commission" => ['exp', "total_manage_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计管理佣金失败");
        }
    }

    //代理佣金
    public function commissionAgent($uid, $money, $order_id)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_AGENT2, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_agent_commission" => ['exp', "total_agent_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计代理佣金失败");
        }
    }

    //推荐代理佣金
    public function commissionAgent2($uid, $money, $order_id)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_AGENT, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_agent2_commission" => ['exp', "total_agent2_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计推荐代理佣金失败");
        }
    }



//推荐代理佣金
    public function commissionShare($uid, $money, $order_id)
    {
        if($money<=0) return false;
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_AGENT, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_agent2_commission" => ['exp', "total_agent2_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计推荐代理佣金失败");
        }
    }


    //重消佣金
    public function commissionRebuy($uid, $money, $order_id)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_REBUY, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_rebuy_commission" => ['exp', "total_rebuy_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计重复消费佣金失败");
        }
    }

    //业绩佣金（月发放）
    public function commissionYeji($uid, $money, $order_id)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_YEJI, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_yeji_commission" => ['exp', "total_yeji_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计业绩佣金失败");
        }
    }



    //一代销售佣金
    public function commissionParent($uid, $money, $order_id)
    {
        $this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_COMMISSION_PARENT, $order_id);
        $update = M('user')->where(['uid' => $uid])->save([
            'update_time' => date('Y-m-d H:i:s'),
            'total_commission' => ['exp', "total_commission+$money"],
            "total_parent_commission" => ['exp', "total_parent_commission+$money"],
        ]);
        if ($update === false) {
            throw new \Exception("累计一代销售佣金失败");
        }
    }
    
    //产生代理结算记录
    public function settleAgent($uid, $agentFee,$percent,$settle_id)
    {
    	//$this->changeBalance($uid, $agentFee*$percent, self::MONEY_LOG_TYPE_AGENT);//更新余额
    	OE('user')->addAgentBoundsCommission($uid, $agentFee, $percent,$settle_id);//添加佣金记录
    }
    
    //代理结算
    public function settleAgentBounds($uid, $money)
    {
    	$this->changeBalance($uid, $money, self::MONEY_LOG_TYPE_AGENT);//更新余额
    }

    //更新余额
    protected function changeBalance($uid, $change_money, $type, $type_id = 0)
    {
        $user = OE('user')->getUserInfo($uid);
        $income = 0;
        $expense = 0;
        if ($change_money < 0) {
            if (abs($change_money) > $user['balance']) {
                throw new \Exception("余额不足");
            }
            //-余额
            $new_balance = $user['balance'] - abs($change_money);
            $expense = abs($change_money);
        } else {
            $new_balance = $user['balance'] + $change_money;
            $income = $change_money;
        }

        if ($change_money != 0) {
            $update = M('user')->where(['uid' => $uid])->save([
                'balance' => $new_balance,
                'update_time' => date('Y-m-d H:i:s'),
                'total_income' => ['exp', "total_income+$income"],
                'total_expense' => ['exp', "total_expense+$expense"],
            ]);
            if ($update === false) {
                throw new \Exception("余额更新失败");
            }
        }

        //资金日志
        $insert_id = $this->add([
            'uid' => $uid,
            'type' => $type,
            'type_id' => $type_id,
            'change_money' => $change_money,
            'old_balance' => $user['balance'],
            'new_balance' => $new_balance,
            'create_time' => date('Y-m-d H:i:s')
        ]);
        if (!$insert_id) {
            throw new \Exception("资金日志记录失败");
        }

        return true;
    }
}